/**
 * 
 */
package hu.gbalage.httpserver;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.osgi.framework.Bundle;

import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

/**
 * @author Grill Balazs (balage.g@gmail.com)
 *
 */
public class HTTPServerRegistry {

	private final Map<String, HTTPServerEntry> entries = new HashMap<String, HTTPServerEntry>(); 
	
	private void add(HTTPServerEntry entry){
		entries.put(entry.getId(), entry);
	}
	
	public HttpServer get(String id){
		if (entries.containsKey(id)) return entries.get(id).getServer();
		return null;
	}
	
	public class HTTPServerEntry{
		
		private final IConfigurationElement element;
		
		private final String nsidentifier;
		
		public HTTPServerEntry(IConfigurationElement element,String nsidentifier) {
			this.element = element;
			this.nsidentifier = nsidentifier;
		}
		
		public String getId(){
			//return element.getAttribute(Constants.EPA_HTTPSERVER_ID);
			return "any";
		}
		
		public int getPort(){
			String port = element.getAttribute(Constants.EPA_HTTPSERVER_PORT);
			return Integer.parseInt(port);
		}
		
		private HttpServer server = null;
		
		public HttpServer getServer(){
			if (server == null) server = createServer();
			return server;
		}
		
		private HttpServer createServer(){
			 try {
				HttpServer server = HttpServer.create(new InetSocketAddress(getPort()), 0);
				server.setExecutor(Executors.newCachedThreadPool());
				getContexts(server, element);
				return server;
			} catch (IOException e) {
				e.printStackTrace();
			} catch (CoreException e) {
				e.printStackTrace();
			}
			return null;
		}
		
		private void getContexts(HttpServer server, IConfigurationElement element) throws CoreException{
			for(IConfigurationElement context : element.getChildren()){
				String path = context.getAttribute("path");
				IConfigurationElement handler = context.getChildren()[0];
				System.out.println("Context at: "+path);
				if (handler.getName().equals("handler")){
					HttpHandler ch = (HttpHandler)handler.createExecutableExtension("handlerClass");
					server.createContext(path, ch);
					System.out.println("Handler of "+ch.getClass());
				}else
				if (handler.getName().equals("file")){
					//System.out.println(nsidentifier);
					Bundle bundle = Platform.getBundle(nsidentifier);
					URL url = bundle.getResource(handler.getAttribute("resource"));
					//HttpSingleFile ch;

						HttpHandler ch =  new HttpURLReaderHandler(url);//new HttpSingleFile(url.openStream());
						HttpContext httpcontext = server.createContext(path);
						httpcontext.setHandler(ch);
						System.out.println("Internal error handler");
						System.out.println("Resource of "+url);

				}else
					System.out.println("Unknown handler type: "+handler.getName());
			}
		}
		
	}
	
	
	public HTTPServerRegistry(){
		IExtensionRegistry registry = Platform.getExtensionRegistry();  
		IExtensionPoint point = registry.getExtensionPoint(Constants.EP_HTTPSERVER);
		for (IExtension extension : point.getExtensions()){  
			for (IConfigurationElement element : extension.getConfigurationElements()){
				add(new HTTPServerEntry(element,extension.getNamespaceIdentifier()));
			}
		}
	}
	
	public void start(){
		for(HTTPServerEntry entry : entries.values()){
			System.out.println("starting server: "+entry.getId()+" on port "+entry.getPort());
			entry.getServer().start();
		}
	}
	
	public void stop(){
		for(HTTPServerEntry entry : entries.values()){
			entry.getServer().stop(0);
		}
	}
	
}
